package com.huawei.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ClientRequestException;
import com.huaweicloud.sdk.core.exception.ServerResponseException;
import com.huaweicloud.sdk.er.v3.ErClient;
import com.huaweicloud.sdk.er.v3.model.CreateEnterpriseRouterRequest;
import com.huaweicloud.sdk.er.v3.model.CreateEnterpriseRouterRequestBody;
import com.huaweicloud.sdk.er.v3.model.CreateEnterpriseRouterResponse;
import com.huaweicloud.sdk.er.v3.model.DeleteEnterpriseRouterRequest;
import com.huaweicloud.sdk.er.v3.model.DeleteEnterpriseRouterResponse;
import com.huaweicloud.sdk.er.v3.model.ListEnterpriseRoutersRequest;
import com.huaweicloud.sdk.er.v3.model.ListEnterpriseRoutersResponse;
import com.huaweicloud.sdk.er.v3.model.ShowEnterpriseRouterRequest;
import com.huaweicloud.sdk.er.v3.model.ShowEnterpriseRouterResponse;
import com.huaweicloud.sdk.er.v3.model.UpdateEnterpriseRouterRequest;
import com.huaweicloud.sdk.er.v3.model.UpdateEnterpriseRouterRequestBody;
import com.huaweicloud.sdk.er.v3.model.UpdateEnterpriseRouterResponse;
import com.huaweicloud.sdk.er.v3.region.ErRegion;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Function;

public class EnterpriseRouterInstanceDemo {
    private static final Logger LOGGER = LoggerFactory.getLogger(EnterpriseRouterInstanceDemo.class.getName());

    public static void main(String[] args) {
        String ak = "<your ak>";
        String sk = "<your sk>";
        String erId = "{er_id}";

        ICredential auth = new BasicCredentials()
            .withAk(ak)
            .withSk(sk);

        ErClient client = ErClient.newBuilder()
            .withCredential(auth)
            .withRegion(ErRegion.valueOf("cn-south-1"))
            .build();

        // Create enterprise router
        createEnterpriseRouter(client);

        /*
         * the parameter erId can be extracted from response of the previous function
         */
        // Update enterprise router
        updateEnterpriseRouter(client, erId);

        // Show enterprise router
        showEnterpriseRouter(client, erId);

        // Delete enterprise router
        deleteEnterpriseRouter(client, erId);

        // List enterprise routers
        listEnterpriseRouters(client);

    }

    private static CreateEnterpriseRouterResponse createEnterpriseRouter(ErClient client) {
        CreateEnterpriseRouterRequest request = new CreateEnterpriseRouterRequest();
        CreateEnterpriseRouterRequestBody body = new CreateEnterpriseRouterRequestBody();

        body.withInstance(instance -> {
            instance.withName("<your enterprise router name>");
            instance.withDescription("<your enterprise router description>");
            instance.withAvailabilityZoneIds(azs -> azs.add("<availablility zone id>"));
            instance.withEnableDefaultAssociation(false);
            instance.withEnableDefaultPropagation(false);
            instance.withAsn(64512L); // AS number
        });
        request.withBody(body);

        Function<Void, CreateEnterpriseRouterResponse> task = (Void v) -> {
            return client.createEnterpriseRouter(request);
        };
        return execute(task);
    }

    private static ShowEnterpriseRouterResponse showEnterpriseRouter(ErClient client, String erId) {
        ShowEnterpriseRouterRequest request = new ShowEnterpriseRouterRequest().withErId(erId);
        Function<Void, ShowEnterpriseRouterResponse> task = (Void v) -> {
            return client.showEnterpriseRouter(request);
        };
        return execute(task);
    }

    private static UpdateEnterpriseRouterResponse updateEnterpriseRouter(ErClient client, String erId) {
        UpdateEnterpriseRouterRequest request = new UpdateEnterpriseRouterRequest();
        UpdateEnterpriseRouterRequestBody body = new UpdateEnterpriseRouterRequestBody();
        body.withInstance(instance -> {
            instance.withName("<your new enterprise router name>");
            instance.withDescription("<your new enterprise router description>");
        });
        request.withErId(erId).withBody(body);
        Function<Void, UpdateEnterpriseRouterResponse> task = (Void v) -> {
            return client.updateEnterpriseRouter(request);
        };
        return execute(task);
    }

    private static void deleteEnterpriseRouter(ErClient client, String erId) {
        DeleteEnterpriseRouterRequest request = new DeleteEnterpriseRouterRequest().withErId(erId);
        Function<Void, DeleteEnterpriseRouterResponse> task = (Void v) -> {
            return client.deleteEnterpriseRouter(request);
        };
        execute(task);
    }

    private static ListEnterpriseRoutersResponse listEnterpriseRouters(ErClient client) {
        ListEnterpriseRoutersRequest request = new ListEnterpriseRoutersRequest();
        Function<Void, ListEnterpriseRoutersResponse> task = (Void v) -> {
            return client.listEnterpriseRouters(request);
        };
        return execute(task);
    }

    private static <T> T execute(Function<Void, T> task) {
        T response = null;
        try {
            response = task.apply(null);
            LOGGER.info(response.toString());
        } catch (ClientRequestException e) {
            LOGGER.error(String.valueOf(e.getHttpStatusCode()));
            LOGGER.error(e.toString());
        } catch (ServerResponseException e) {
            LOGGER.error(String.valueOf(e.getHttpStatusCode()));
            LOGGER.error(e.getMessage());
        }
        return response;
    }

}
